{ "cells": [ { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "# IPython: beyond plain Python" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "When executing code in IPython, all valid Python syntax works as-is, but IPython provides a number of features designed to make the interactive experience more fluid and efficient." ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## First things first: running code, getting help" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "In the notebook, to run a cell of code, hit `Shift-Enter`. This executes the cell and puts the cursor in the next cell below, or makes a new one if you are at the end. Alternately, you can use:\n", " \n", "- `Alt-Enter` to force the creation of a new cell unconditionally (useful when inserting new content in the middle of an existing notebook).\n", "- `Control-Enter` executes the cell and keeps the cursor in the same cell, useful for quick experimentation of snippets that you don't need to keep permanently." ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Hi\n" ] } ], "source": [ "print(\"Hi\")" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "Getting help:" ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "collapsed": true }, "outputs": [], "source": [ "?" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "Typing `object_name?` will print all sorts of details about any object, including docstrings, function definition lines (for call arguments) and constructor details for classes." ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "collapsed": true }, "outputs": [], "source": [ "import collections\n", "collections.namedtuple?" ] }, { "cell_type": "code", "execution_count": 4, "metadata": { "collapsed": true }, "outputs": [], "source": [ "collections.Counter??" ] }, { "cell_type": "code", "execution_count": 5, "metadata": { "collapsed": true }, "outputs": [], "source": [ "*int*?" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "An IPython quick reference card:" ] }, { "cell_type": "code", "execution_count": 6, "metadata": { "collapsed": true }, "outputs": [], "source": [ "%quickref" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## Tab completion" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Tab completion, especially for attributes, is a convenient way to explore the structure of any object you’re dealing with. Simply type `object_name.` to view the object’s attributes. Besides Python objects and keywords, tab completion also works on file and directory names." ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [], "source": [ "collections." ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## The interactive workflow: input, output, history" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "12" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "2+10" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "22" ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "_+10" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "You can suppress the storage and rendering of output if you append `;` to the last cell (this comes in handy when plotting with matplotlib, for example):" ] }, { "cell_type": "code", "execution_count": 9, "metadata": { "collapsed": true }, "outputs": [], "source": [ "10+20;" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "22" ] }, "execution_count": 10, "metadata": {}, "output_type": "execute_result" } ], "source": [ "_" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "The output is stored in `_N` and `Out[N]` variables:" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "True" ] }, "execution_count": 11, "metadata": {}, "output_type": "execute_result" } ], "source": [ "_10 == Out[10]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Previous inputs are available, too:" ] }, { "cell_type": "code", "execution_count": 12, "metadata": { "slideshow": { "slide_type": "-" } }, "outputs": [ { "data": { "text/plain": [ "'_10 == Out[10]'" ] }, "execution_count": 12, "metadata": {}, "output_type": "execute_result" } ], "source": [ "In[11]" ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'In[11]'" ] }, "execution_count": 13, "metadata": {}, "output_type": "execute_result" } ], "source": [ "_i" ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " 1: print(\"Hi\")\n", " 2: ?\n", " 3:\n", "import collections\n", "collections.namedtuple?\n", " 4: collections.Counter??\n", " 5: *int*?\n" ] } ], "source": [ "%history -n 1-5" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## Accessing the underlying operating system" ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "/Users/fperez/teach/berkeley/2017-stat159/stat159/lectures/02-ipython\r\n" ] } ], "source": [ "!pwd" ] }, { "cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "My current directory's files:\n", "['Beyond Plain Python.ipynb', 'Index.ipynb', 'Notebook Basics.ipynb', 'Working With Markdown Cells.ipynb', '__pycache__', 'images', 'mod.py', 'test.txt']\n" ] } ], "source": [ "files = !ls\n", "print(\"My current directory's files:\")\n", "print(files)" ] }, { "cell_type": "code", "execution_count": 17, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[Beyond Plain Python.ipynb, Index.ipynb, Notebook Basics.ipynb, Working With Markdown Cells.ipynb, __pycache__, images, mod.py, test.txt]\r\n" ] } ], "source": [ "!echo $files" ] }, { "cell_type": "code", "execution_count": 18, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "BEYOND PLAIN PYTHON.IPYNB\r\n" ] } ], "source": [ "!echo {files[0].upper()}" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Note that all this is available even in multiline blocks:" ] }, { "cell_type": "code", "execution_count": 19, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "00 - Beyond Plain Python\n", "01 - Index\n", "02 - Notebook Basics\n", "03 - Working With Markdown Cells\n", "--\n", "--\n", "--\n", "--\n" ] } ], "source": [ "import os\n", "for i,f in enumerate(files):\n", " if f.endswith('ipynb'):\n", " !echo {\"%02d\" % i} - \"{os.path.splitext(f)[0]}\"\n", " else:\n", " print('--')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Beyond Python: magic functions" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The IPyhton 'magic' functions are a set of commands, invoked by prepending one or two `%` signs to their name, that live in a namespace separate from your normal Python variables and provide a more command-like interface. They take flags with `--` and arguments without quotes, parentheses or commas. The motivation behind this system is two-fold:\n", " \n", "- To provide an orthogonal namespace for controlling IPython itself and exposing other system-oriented functionality.\n", "\n", "- To expose a calling mode that requires minimal verbosity and typing while working interactively. Thus the inspiration taken from the classic Unix shell style for commands." ] }, { "cell_type": "code", "execution_count": 20, "metadata": { "collapsed": true }, "outputs": [], "source": [ "%magic" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Line vs cell magics:" ] }, { "cell_type": "code", "execution_count": 21, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "12.5 µs ± 102 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)\n" ] } ], "source": [ "%timeit list(range(1000))" ] }, { "cell_type": "code", "execution_count": 27, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1.87 µs ± 53.8 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)\n" ] } ], "source": [ "%%timeit -n 100000\n", "x = list(range(100))\n", "sum(x)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Line magics can be used even inside code blocks:" ] }, { "cell_type": "code", "execution_count": 30, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "size: 100 1.02 µs ± 38.1 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)\n", "size: 200 1.4 µs ± 57.4 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)\n", "size: 300 2.35 µs ± 39 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)\n", "size: 400 3.82 µs ± 41.2 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)\n" ] } ], "source": [ "for i in range(1, 5):\n", " size = i*100\n", " print('size:', size, end=' ')\n", " %timeit -n 100000 list(range(size))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Magics can do anything they want with their input, so it doesn't have to be valid Python:" ] }, { "cell_type": "code", "execution_count": 31, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "My shell is: /usr/local/bin/bash\n", "My disk usage is:\n", "Filesystem Size Used Avail Capacity iused ifree %iused Mounted on\n", "/dev/disk1 931Gi 501Gi 429Gi 54% 3005697 4291961582 0% /\n", "devfs 192Ki 192Ki 0Bi 100% 664 0 100% /dev\n", "map -hosts 0Bi 0Bi 0Bi 100% 0 0 100% /net\n", "/dev/disk2s2 1.8Ti 517Gi 1.3Ti 28% 4360270 4290607009 0% /Volumes/Time Machine - Seagate Silver\n" ] } ], "source": [ "%%bash\n", "echo \"My shell is:\" $SHELL\n", "echo \"My disk usage is:\"\n", "df -h" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Another interesting cell magic: create any file you want locally from the notebook:" ] }, { "cell_type": "code", "execution_count": 32, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Overwriting test.txt\n" ] } ], "source": [ "%%writefile test.txt\n", "This is a test file!\n", "It can contain anything I want...\n", "\n", "And more..." ] }, { "cell_type": "code", "execution_count": 33, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "This is a test file!\r\n", "It can contain anything I want...\r\n", "\r\n", "And more..." ] } ], "source": [ "!cat test.txt" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Let's see what other magics are currently defined in the system:" ] }, { "cell_type": "code", "execution_count": 34, "metadata": {}, "outputs": [ { "data": { "application/json": { "cell": { "!": "OSMagics", "HTML": "Other", "SVG": "Other", "bash": "Other", "capture": "ExecutionMagics", "debug": "ExecutionMagics", "file": "Other", "html": "DisplayMagics", "javascript": "DisplayMagics", "js": "DisplayMagics", "latex": "DisplayMagics", "markdown": "DisplayMagics", "perl": "Other", "prun": "ExecutionMagics", "pypy": "Other", "python": "Other", "python2": "Other", "python3": "Other", "ruby": "Other", "script": "ScriptMagics", "sh": "Other", "svg": "DisplayMagics", "sx": "OSMagics", "system": "OSMagics", "time": "ExecutionMagics", "timeit": "ExecutionMagics", "writefile": "OSMagics" }, "line": { "alias": "OSMagics", "alias_magic": "BasicMagics", "autocall": "AutoMagics", "automagic": "AutoMagics", "autosave": "KernelMagics", "bookmark": "OSMagics", "cat": "Other", "cd": "OSMagics", "cl": "Other", "clear": "KernelMagics", "colors": "BasicMagics", "config": "ConfigMagics", "connect_info": "KernelMagics", "cp": "Other", "d": "Other", "dd": "Other", "debug": "ExecutionMagics", "dhist": "OSMagics", "dirs": "OSMagics", "dl": "Other", "doctest_mode": "BasicMagics", "dp": "Other", "dus": "Other", "dx": "Other", "ed": "Other", "edit": "KernelMagics", "env": "OSMagics", "gui": "BasicMagics", "hist": "Other", "history": "HistoryMagics", "killbgscripts": "ScriptMagics", "ldir": "Other", "less": "KernelMagics", "lf": "Other", "lk": "Other", "ll": "Other", "load": "CodeMagics", "load_ext": "ExtensionMagics", "loadpy": "CodeMagics", "logoff": "LoggingMagics", "logon": "LoggingMagics", "logstart": "LoggingMagics", "logstate": "LoggingMagics", "logstop": "LoggingMagics", "ls": "Other", "lsmagic": "BasicMagics", "lx": "Other", "macro": "ExecutionMagics", "magic": "BasicMagics", "man": "KernelMagics", "matplotlib": "PylabMagics", "mkdir": "Other", "more": "KernelMagics", "mv": "Other", "notebook": "BasicMagics", "page": "BasicMagics", "pastebin": "CodeMagics", "pdb": "ExecutionMagics", "pdef": "NamespaceMagics", "pdoc": "NamespaceMagics", "pfile": "NamespaceMagics", "pinfo": "NamespaceMagics", "pinfo2": "NamespaceMagics", "pip": "BasicMagics", "popd": "OSMagics", "pprint": "BasicMagics", "precision": "BasicMagics", "profile": "BasicMagics", "prun": "ExecutionMagics", "psearch": "NamespaceMagics", "psource": "NamespaceMagics", "pushd": "OSMagics", "pwd": "OSMagics", "pycat": "OSMagics", "pylab": "PylabMagics", "qtconsole": "KernelMagics", "quickref": "BasicMagics", "recall": "HistoryMagics", "rehashx": "OSMagics", "reload_ext": "ExtensionMagics", "rep": "Other", "rerun": "HistoryMagics", "reset": "NamespaceMagics", "reset_selective": "NamespaceMagics", "rm": "Other", "rmdir": "Other", "run": "ExecutionMagics", "save": "CodeMagics", "sc": "OSMagics", "set_env": "OSMagics", "store": "StoreMagics", "sx": "OSMagics", "system": "OSMagics", "tb": "ExecutionMagics", "time": "ExecutionMagics", "timeit": "ExecutionMagics", "unalias": "OSMagics", "unload_ext": "ExtensionMagics", "who": "NamespaceMagics", "who_ls": "NamespaceMagics", "whos": "NamespaceMagics", "xdel": "NamespaceMagics", "xmode": "BasicMagics" } }, "text/plain": [ "Available line magics:\n", "%alias %alias_magic %autocall %automagic %autosave %bookmark %cat %cd %cl %clear %colors %config %connect_info %cp %d %dd %debug %dhist %dirs %dl %doctest_mode %dp %dus %dx %ed %edit %env %gui %hist %history %killbgscripts %ldir %less %lf %lk %ll %load %load_ext %loadpy %logoff %logon %logstart %logstate %logstop %ls %lsmagic %lx %macro %magic %man %matplotlib %mkdir %more %mv %notebook %page %pastebin %pdb %pdef %pdoc %pfile %pinfo %pinfo2 %popd %pprint %precision %profile %prun %psearch %psource %pushd %pwd %pycat %pylab %qtconsole %quickref %recall %rehashx %reload_ext %rep %rerun %reset %reset_selective %rm %rmdir %run %save %sc %set_env %store %sx %system %tb %time %timeit %unalias %unload_ext %who %who_ls %whos %xdel %xmode\n", "\n", "Available cell magics:\n", "%%! %%HTML %%SVG %%bash %%capture %%debug %%file %%html %%javascript %%js %%latex %%markdown %%perl %%prun %%pypy %%python %%python2 %%python3 %%ruby %%script %%sh %%svg %%sx %%system %%time %%timeit %%writefile\n", "\n", "Automagic is ON, % prefix IS NOT needed for line magics." ] }, "execution_count": 34, "metadata": {}, "output_type": "execute_result" } ], "source": [ "%lsmagic" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Running normal Python code: execution and errors" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Not only can you input normal Python code, you can even paste straight from a Python or IPython shell session:" ] }, { "cell_type": "code", "execution_count": 35, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1\n", "1\n", "2\n", "3\n", "5\n", "8\n" ] } ], "source": [ ">>> # Fibonacci series:\n", "... # the sum of two elements defines the next\n", "... a, b = 0, 1\n", ">>> while b < 10:\n", "... print(b)\n", "... a, b = b, a+b" ] }, { "cell_type": "code", "execution_count": 36, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "0 1 2 3 4 5 6 7 8 9 " ] } ], "source": [ "In [1]: for i in range(10):\n", " ...: print(i, end=' ')\n", " ...: " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "And when your code produces errors, you can control how they are displayed with the `%xmode` magic:" ] }, { "cell_type": "code", "execution_count": 37, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Overwriting mod.py\n" ] } ], "source": [ "%%writefile mod.py\n", "\n", "def f(x):\n", " return 1.0/(x-1)\n", "\n", "def g(y):\n", " return f(y+1)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Now let's call the function `g` with an argument that would produce an error:" ] }, { "cell_type": "code", "execution_count": 38, "metadata": {}, "outputs": [ { "ename": "ZeroDivisionError", "evalue": "float division by zero", "output_type": "error", "traceback": [ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mZeroDivisionError\u001b[0m Traceback (most recent call last)", "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[0;32mimport\u001b[0m \u001b[0mmod\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 2\u001b[0;31m \u001b[0mmod\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mg\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m0\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[0;32m~/teach/berkeley/2017-stat159/stat159/lectures/02-ipython/mod.py\u001b[0m in \u001b[0;36mg\u001b[0;34m(y)\u001b[0m\n\u001b[1;32m 4\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 5\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mg\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0my\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 6\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0mf\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0my\u001b[0m\u001b[0;34m+\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[0;32m~/teach/berkeley/2017-stat159/stat159/lectures/02-ipython/mod.py\u001b[0m in \u001b[0;36mf\u001b[0;34m(x)\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 2\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mf\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mx\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 3\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0;36m1.0\u001b[0m\u001b[0;34m/\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mx\u001b[0m\u001b[0;34m-\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 4\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 5\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mg\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0my\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", "\u001b[0;31mZeroDivisionError\u001b[0m: float division by zero" ] } ], "source": [ "import mod\n", "mod.g(0)" ] }, { "cell_type": "code", "execution_count": 39, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Exception reporting mode: Plain\n" ] }, { "ename": "ZeroDivisionError", "evalue": "float division by zero", "output_type": "error", "traceback": [ "Traceback \u001b[0;36m(most recent call last)\u001b[0m:\n", " File \u001b[1;32m\"\"\u001b[0m, line \u001b[1;32m2\u001b[0m, in \u001b[1;35m\u001b[0m\n mod.g(0)\n", " File \u001b[1;32m\"/Users/fperez/teach/berkeley/2017-stat159/stat159/lectures/02-ipython/mod.py\"\u001b[0m, line \u001b[1;32m6\u001b[0m, in \u001b[1;35mg\u001b[0m\n return f(y+1)\n", "\u001b[0;36m File \u001b[0;32m\"/Users/fperez/teach/berkeley/2017-stat159/stat159/lectures/02-ipython/mod.py\"\u001b[0;36m, line \u001b[0;32m3\u001b[0;36m, in \u001b[0;35mf\u001b[0;36m\u001b[0m\n\u001b[0;31m return 1.0/(x-1)\u001b[0m\n", "\u001b[0;31mZeroDivisionError\u001b[0m\u001b[0;31m:\u001b[0m float division by zero\n" ] } ], "source": [ "%xmode plain\n", "mod.g(0)" ] }, { "cell_type": "code", "execution_count": 40, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Exception reporting mode: Verbose\n" ] }, { "ename": "ZeroDivisionError", "evalue": "float division by zero", "output_type": "error", "traceback": [ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mZeroDivisionError\u001b[0m Traceback (most recent call last)", "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[0mget_ipython\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mrun_line_magic\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'xmode'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m'verbose'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 2\u001b[0;31m \u001b[0mmod\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mg\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m0\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m \u001b[0;36mglobal\u001b[0m \u001b[0;36mmod.g\u001b[0m \u001b[0;34m= \u001b[0m\n", "\u001b[0;32m~/teach/berkeley/2017-stat159/stat159/lectures/02-ipython/mod.py\u001b[0m in \u001b[0;36mg\u001b[0;34m(y=0)\u001b[0m\n\u001b[1;32m 4\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 5\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mg\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0my\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 6\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0mf\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0my\u001b[0m\u001b[0;34m+\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m \u001b[0;36mglobal\u001b[0m \u001b[0;36mf\u001b[0m \u001b[0;34m= \u001b[0m\u001b[0;34m\n \u001b[0m\u001b[0;36my\u001b[0m \u001b[0;34m= 0\u001b[0m\n", "\u001b[0;32m~/teach/berkeley/2017-stat159/stat159/lectures/02-ipython/mod.py\u001b[0m in \u001b[0;36mf\u001b[0;34m(x=1)\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 2\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mf\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mx\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 3\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0;36m1.0\u001b[0m\u001b[0;34m/\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mx\u001b[0m\u001b[0;34m-\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m \u001b[0;36mx\u001b[0m \u001b[0;34m= 1\u001b[0m\n\u001b[1;32m 4\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 5\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mg\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0my\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", "\u001b[0;31mZeroDivisionError\u001b[0m: float division by zero" ] } ], "source": [ "%xmode verbose\n", "mod.g(0)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The default `%xmode` is \"context\", which shows additional context but not all local variables. Let's restore that one for the rest of our session." ] }, { "cell_type": "code", "execution_count": 41, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Exception reporting mode: Context\n" ] } ], "source": [ "%xmode context" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Running code in other languages with special `%%` magics" ] }, { "cell_type": "code", "execution_count": 42, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "July" ] } ], "source": [ "%%perl\n", "@months = (\"July\", \"August\", \"September\");\n", "print $months[0];" ] }, { "cell_type": "code", "execution_count": 43, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Hello World!\n" ] } ], "source": [ "%%ruby\n", "name = \"world\"\n", "puts \"Hello #{name.capitalize}!\"" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Raw Input in the notebook" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Since 1.0 the IPython notebook web application support `raw_input` which for example allow us to invoke the `%debug` magic in the notebook:" ] }, { "cell_type": "code", "execution_count": 44, "metadata": {}, "outputs": [ { "ename": "ZeroDivisionError", "evalue": "float division by zero", "output_type": "error", "traceback": [ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mZeroDivisionError\u001b[0m Traceback (most recent call last)", "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mmod\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mg\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m0\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[0;32m~/teach/berkeley/2017-stat159/stat159/lectures/02-ipython/mod.py\u001b[0m in \u001b[0;36mg\u001b[0;34m(y)\u001b[0m\n\u001b[1;32m 4\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 5\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mg\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0my\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 6\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0mf\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0my\u001b[0m\u001b[0;34m+\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[0;32m~/teach/berkeley/2017-stat159/stat159/lectures/02-ipython/mod.py\u001b[0m in \u001b[0;36mf\u001b[0;34m(x)\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 2\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mf\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mx\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 3\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0;36m1.0\u001b[0m\u001b[0;34m/\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mx\u001b[0m\u001b[0;34m-\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 4\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 5\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mg\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0my\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", "\u001b[0;31mZeroDivisionError\u001b[0m: float division by zero" ] } ], "source": [ "mod.g(0)" ] }, { "cell_type": "code", "execution_count": 46, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "> \u001b[0;32m/Users/fperez/teach/berkeley/2017-stat159/stat159/lectures/02-ipython/mod.py\u001b[0m(3)\u001b[0;36mf\u001b[0;34m()\u001b[0m\n", "\u001b[0;32m 1 \u001b[0;31m\u001b[0;34m\u001b[0m\u001b[0m\n", "\u001b[0m\u001b[0;32m 2 \u001b[0;31m\u001b[0;32mdef\u001b[0m \u001b[0mf\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mx\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", "\u001b[0m\u001b[0;32m----> 3 \u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0;36m1.0\u001b[0m\u001b[0;34m/\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mx\u001b[0m\u001b[0;34m-\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", "\u001b[0m\u001b[0;32m 4 \u001b[0;31m\u001b[0;34m\u001b[0m\u001b[0m\n", "\u001b[0m\u001b[0;32m 5 \u001b[0;31m\u001b[0;32mdef\u001b[0m \u001b[0mg\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0my\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", "\u001b[0m\n", "ipdb> q\n" ] } ], "source": [ "%debug" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Don't foget to exit your debugging session. Raw input can of course be use to ask for user input:" ] }, { "cell_type": "code", "execution_count": 47, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Are you enjoying this tutorial? yes!\n", "enjoy is: yes!\n" ] } ], "source": [ "enjoy = input('Are you enjoying this tutorial? ')\n", "print('enjoy is:', enjoy)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Plotting in the notebook" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "This magic configures matplotlib to render its figures inline:" ] }, { "cell_type": "code", "execution_count": 48, "metadata": { "collapsed": true }, "outputs": [], "source": [ "%matplotlib inline" ] }, { "cell_type": "code", "execution_count": 49, "metadata": { "collapsed": true }, "outputs": [], "source": [ "import numpy as np\n", "import matplotlib.pyplot as plt" ] }, { "cell_type": "code", "execution_count": 50, "metadata": {}, "outputs": [ { "data": { "image/png": "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\nrkJggg==\n", "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "x = np.linspace(0, 2*np.pi, 300)\n", "y = np.sin(x**2)\n", "plt.plot(x, y)\n", "plt.title(\"A little chirp\")\n", "fig = plt.gcf() # let's keep the figure object around for later..." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## The IPython kernel/client model" ] }, { "cell_type": "code", "execution_count": 51, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "{\n", " \"shell_port\": 61750,\n", " \"iopub_port\": 61751,\n", " \"stdin_port\": 61752,\n", " \"control_port\": 61753,\n", " \"hb_port\": 61754,\n", " \"ip\": \"127.0.0.1\",\n", " \"key\": \"7cf2d8a1-64149f698b1ca4929d44b73a\",\n", " \"transport\": \"tcp\",\n", " \"signature_scheme\": \"hmac-sha256\",\n", " \"kernel_name\": \"\"\n", "}\n", "\n", "Paste the above JSON into a file, and connect with:\n", " $> jupyter --existing \n", "or, if you are local, you can connect with just:\n", " $> jupyter --existing kernel-90b8bcf0-cc04-4407-b44f-22dbcb1d2bca.json\n", "or even just:\n", " $> jupyter --existing\n", "if this is the most recent Jupyter kernel you have started.\n" ] } ], "source": [ "%connect_info" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can connect automatically a Qt Console to the currently running kernel with the `%qtconsole` magic, or by typing `ipython console --existing ` in any terminal:" ] }, { "cell_type": "code", "execution_count": 52, "metadata": { "collapsed": true }, "outputs": [], "source": [ "%qtconsole" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.6.2" } }, "nbformat": 4, "nbformat_minor": 1 }